'use strict';
const Service = require('egg').Service;
const lodash = require('lodash');

class AdminService extends Service {

  // 分页列表
  async pageList(condition, page = 1, order = []) {
    // read config
    const { pageSize } = this.config.common;
    const offset = (page - 1) * pageSize;
    if (!Object.keys(condition)) condition = { 1: 1 };
    if (!order.length) order = [[ 'add_time', 'desc' ], [ 'admin_id', 'desc' ]];
    const results = this.ctx.model.Admin.findAndCount({
      where: condition,
      order,
      limit: pageSize,
      offset,
      raw: true,
    });
    return results;
  }

  // 登录时间记录
  async loginRecord(admin_id) {
    const update_data = {
      last_login: this.ctx.helper.date_to_time(),
      last_ip: this.ctx.request.ip,
    };
    const res = await this.ctx.model.Admin.update(update_data, { where: { admin_id } });
    return res[0];
  }

  /* 通过ID获取权限*/
  async getAdminRule(role_id) {
    return await this.ctx.model.Adminrole.findById(role_id, { raw: true });
  }

  // 获取权限列表
  async getRoleList(condition, limit = 10, order = []) {
    if (!Object.keys(condition)) condition = { 1: 1 };
    if (!order.length) order = [[ 'role_id', 'desc' ]];
    const results = this.ctx.model.Adminrole.findAll({
      where: condition,
      order,
      limit,
      raw: true,
    });
    return results;
  }

  // 获取权限菜单
  async getRoluMenu(act_list) {
    const { Op } = this.app.Sequelize;
    const menu_list = await this.ctx.model.Systemmodule.findAll({
      where: { level: { [Op.gt]: 1 }, visible: 1 },
      order: [[ 'orderby', 'desc' ], [ 'mod_id', 'desc' ]],
      raw: true,
    });
    const res = [];
    const res_menu_list = {}; // 子菜单{pid:[item1,item2...]}
    const pmenu = {}; // 父菜单 {`_${mod_id}`:item}
    if (act_list === 'all') {
      menu_list.forEach(item => {
        if (item.level === 3) {
          if (!Array.isArray(res_menu_list[item.parent_id])) {
            res_menu_list[item.parent_id] = [];
          }
          item.url = '/admin/' + item.ctl + '/' + item.act;
          res_menu_list[item.parent_id].push(item);// 子菜单分组
        }
        if (item.level === 2) {
          pmenu['_' + item.mod_id] = item;// 二级父菜单，添加下划线防止对象自动排序
        }
      });
    } else {
      const act_list_arr = act_list.split(',');
      menu_list.forEach(item => {
        if (act_list_arr.includes('' + item.mod_id)) { // 判断菜单是否在权限列表里
          item.url = '/admin/' + item.ctl + '/' + item.act;
          if (!Array.isArray(res_menu_list[item.parent_id])) {
            res_menu_list[item.parent_id] = [];
          }
          res_menu_list[item.parent_id].push(item);
        }
        if (item.level === 2) {
          pmenu['_' + item.mod_id] = item;// 二级父菜单
        }
      });
    }
    const pmenu_keys = Object.keys(pmenu);
    if (pmenu_keys.length) {
      pmenu_keys.forEach(item => {
        if (Array.isArray(res_menu_list[item.slice(1)])) {  // 判断去下划线的key是否有子菜单
          pmenu[item].submenu = res_menu_list[item.slice(1)];
          res.push(pmenu[item]);
        }
      });
    }
    return res;
  }

  // 返回角色权限分配时的显示格式
  async getRoleMenuList(act_list) {
    const menu_tree = [];
    const modules = [];
    const menu_list = await this.ctx.model.Systemmodule.findAll({ where: {}, order: [[ 'mod_id', 'asc' ]], raw: true });
    const act_list_arr = act_list ? act_list.split(',') : []; // 切割完成的数组元素为字符串类型
    if (menu_list.length) {
      for (const item of menu_list) {
        item.enable = act_list_arr.includes('' + item.mod_id) ? 1 : 0; // 将mod_id转成字符串类型再进行搜索
        modules[item.mod_id] = item;
      }

    }
    // console.log(modules);
    if (modules.length) {
      modules.forEach((item, k) => {
        if (item.module === 'top') {
          menu_tree[k] = item;
        }
      });
      modules.forEach((item, k) => {
        if (item.module === 'menu') {
          if (!menu_tree[item.parent_id].menu) {
            menu_tree[item.parent_id].menu = [];
          }
          menu_tree[item.parent_id].menu[k] = item;
        }
      });
      modules.forEach((item, k, self) => {
        if (item.module === 'module') {
          const ppk = self[item.parent_id].parent_id;
          if (!menu_tree[ppk].menu[item.parent_id].menu) {
            menu_tree[ppk].menu[item.parent_id].menu = [];
          }
          menu_tree[ppk].menu[item.parent_id].menu[k] = item;
        }
      });
    }
    return menu_tree;
  }

  // 角色分页列表
  async rolePageList(condition, page = 1, order = []) {
    // read config
    const { pageSize } = this.config.common;
    const offset = (page - 1) * pageSize;
    if (!Object.keys(condition)) condition = { 1: 1 };
    if (!order.length) order = [[ 'role_id', 'desc' ]];
    const results = this.ctx.model.Adminrole.findAndCount({
      where: condition,
      order,
      limit: pageSize,
      offset,
      raw: true,
    });
    return results;
  }

  // 管理员日志分页列表
  async logPageList(condition, page = 1, order = []) {
    // read config
    const { pageSize } = this.config.common;
    const offset = (page - 1) * pageSize;
    if (!Object.keys(condition)) condition = { 1: 1 };
    if (!order.length) order = [[ 'log_time', 'desc' ], [ 'log_id', 'desc' ]];
    const results = this.ctx.logModel.Adminlog.findAndCount({
      where: condition,
      order,
      limit: pageSize,
      offset,
      raw: true,
    });
    return results;
  }

  // 错误日志分页列表
  async errLogPageList(condition, page = 1, order = []) {
    // read config
    const { pageSize } = this.config.common;
    const offset = (page - 1) * pageSize;
    if (!Object.keys(condition)) condition = { 1: 1 };
    if (!order.length) order = [[ 'create_time', 'desc' ], [ 'id', 'desc' ]];
    const results = this.ctx.logModel.Errlog.findAndCount({
      where: condition,
      order,
      limit: pageSize,
      offset,
      raw: true,
    });
    return results;
  }

  // 错误日志记录
  async rocordErrLog(msg = '') {
    if (!msg) return;
    const data = { content: msg, create_time: this.ctx.helper.date_to_time() };
    const res = await this.ctx.logModel.Errlog.create(data, { raw: true });
    return !!res;
  }

  // 管理员操作日志记录
  async rocordAdminLog(msg = '') {
    const admin_id = this.ctx.session.admin_id;
    const url = this.ctx.request.url;
    const ip = this.ctx.request.ip;
    if (!admin_id) {
      return this.rocordErrLog('未登录用户进行后台操作');
    }
    if (!msg) return;
    const data = { admin_id, log_info: msg, log_ip: ip, log_url: url, log_time: this.ctx.helper.date_to_time() };
    const res = await this.ctx.logModel.Adminlog.create(data, { raw: true });
    return !!res;
  }

  // 数据库日志分页列表
  async dbLogPageList(condition, page = 1, order = []) {
    // read config
    const { pageSize } = this.config.common;
    const offset = (page - 1) * pageSize;
    if (!Object.keys(condition)) condition = { 1: 1 };
    if (!order.length) order = [[ 'create_time', 'desc' ], [ 'id', 'desc' ]];
    const results = await this.ctx.logModel.Dblog.findAndCount({
      where: condition,
      order,
      limit: pageSize,
      offset,
      raw: true,
    });
    if (results.rows.length) {
      const admin_list = {};
      const admin_ids = [];
      for (const item of results.rows) {
        if (item.admin_id && !admin_ids.includes(item.admin_id)) admin_ids.push(item.admin_id);
      }
      // 获取管理员名
      const admin_name_ids = await this.ctx.model.Admin.findAll({
        where: { admin_id: { [this.app.Sequelize.Op.in]: admin_ids } },
        attributes: [ 'admin_id', 'user_name' ],
        raw: true,
      });
      for (const item of admin_name_ids) {
        admin_list[item.admin_id] = item.user_name;
      }
      results.admin_list = admin_list;
    }
    return results;
  }

  /*
  * 数据库操作日志
  * @param string name 操作名称
  * @param string table 表名
  * @param int|object 数据
  * return
  * */
  async recordDbLog(name, table, data) {
    if (!name || !table || !data || !this.config.common.db_op_record) return false;
    let type = '';
    let note = null;
    if (lodash.isObject(data)) {
      type += data.where ? 'update' : 'insert';
      note = JSON.stringify(data);
    } else {
      type += 'delete';
      note = data;
    }
    const insert_data = { name, admin_id: this.ctx.session.admin_id, table_name: table, type, create_time: this.ctx.helper.date_to_time(), note };
    const res = await this.ctx.logModel.Dblog.create(insert_data, { raw: true });
    return !!res;
  }

}

module.exports = AdminService;
